﻿namespace Sgr.OmniMetrics
{
    public class OmniMetric<T> where T : class
    {
        /// <summary>
        /// 指标唯一标识(可自定义)
        /// </summary>
        public string MetricKey { get; set; } = string.Empty;

        /// <summary>
        /// 统计粒度(按年、月、周、日...)
        /// </summary>
        public Granularity TimeGranularity { get; set; } = Granularity.Day;

        /// <summary>
        /// 统计时间点（对齐到粒度起始，如按天统计存2024-03-20 00:00:00）
        /// </summary>
        public DateTime TimeValue { get; set; } = DateTime.MinValue;

        /// <summary>
        /// 基础数值01（如总量、平均值等标量）
        /// </summary>
        public double BasicValue01 { get; set; } = 0;

        /// <summary>
        /// 基础数值02（如总量、平均值等标量）
        /// </summary>
        public double BasicValue02 { get; set; } = 0;

        /// <summary>
        /// 基础数值03（如总量、平均值等标量）
        /// </summary>
        public double BasicValue03 { get; set; } = 0;

        /// <summary>
        /// 扩展数值（强类型）
        /// </summary>
        public T? ExtendedValues { get; set; }

        /// <summary>
        /// 指标值更新时间
        /// </summary>
        public DateTime UpdateTime { get; set; } = DateTime.MinValue;

        /// <summary>
        /// 指标元数据
        /// </summary>
        public MetricMetadata Metadata { get; set; } = new();

        /// <summary>
        /// 确保时间对齐到统计粒度
        /// </summary>
        public void AlignTimeValue()
        {
            // 防止未初始化或非法时间
            if (TimeValue == DateTime.MinValue)
                TimeValue = DateTime.UtcNow;

            TimeValue = TimeGranularity switch
            {
                Granularity.Minute => new DateTime(
                        TimeValue.Year,
                        TimeValue.Month,
                        TimeValue.Day,
                        TimeValue.Hour,
                        TimeValue.Minute,
                        0,
                        DateTimeKind.Utc),
                Granularity.Hour => new DateTime(
                        TimeValue.Year,
                        TimeValue.Month,
                        TimeValue.Day,
                        TimeValue.Hour,
                        0,
                        0,
                        DateTimeKind.Utc),
                Granularity.Day => TimeValue.EnsureUtc().Date,
                Granularity.Week => TimeValue.EnsureUtc().Date.AddDays(-(int)TimeValue.DayOfWeek),
                Granularity.Month => new DateTime(TimeValue.Year, TimeValue.Month, 1, 0, 0, 0, DateTimeKind.Utc),
                Granularity.Year => new DateTime(TimeValue.Year, 1, 1, 0, 0, 0, DateTimeKind.Utc),
                Granularity.None => TimeValue.EnsureUtc(),
                _ => TimeValue.EnsureUtc()
            };
        }
    }
}